COVID 19 Dashboard for Balkan countries*
Data
# Github
covid19_confirmed_git <-"https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv"
covid19_confirmed_git <- read_csv(url(covid19_confirmed_git))
# Worldometer
## Covid
codivid19_all <- "https://www.worldometers.info/coronavirus/"
main_table <- codivid19_all%>%
xml2::read_html()%>%
html_nodes(xpath='//*[@id="main_table_countries_today"]') %>%
html_table()
main_table <- as.data.frame(main_table)
## Filtering data for Balkan countries (plus Italy and Austria)
balkan <- filter(main_table,Country.Other == "Bosnia and Herzegovina" | Country.Other == "Italy" | Country.Other == "Croatia" | Country.Other == "Serbia" | Country.Other == "Montenegro" | Country.Other == "Slovenia" | Country.Other == "Austria" | Country.Other == "North Macedonia" | Country.Other == "Greece")
# Removing comma from numbers
balkan[c("TotalRecovered","TotalDeaths","TotalCases","NewCases","ActiveCases","Tot.Cases.1M.pop")] <- lapply(balkan[c("TotalRecovered","TotalDeaths","TotalCases","NewCases","ActiveCases","Tot.Cases.1M.pop")], function(x) gsub(",","",x))
# Turning columns to numeric
balkan[c("TotalRecovered","TotalDeaths","TotalCases","NewCases","ActiveCases","Tot.Cases.1M.pop")] <- lapply(balkan[c("TotalRecovered","TotalDeaths","TotalCases","NewCases","ActiveCases","Tot.Cases.1M.pop")], as.numeric)
Curve of confirmed cases
The graph shows the number of confirmed cases by the last date shown.Updates daily at around 23:59 UTC.
# Curve of confirmed cases----
columns <- colnames(covid19_confirmed_git)[5:ncol(covid19_confirmed_git)]
final <-as.data.frame(pivot_longer(covid19_confirmed_git, cols = columns, names_to = "Year", values_to = "Confirmed"))
final$Year <- as.Date.character(final$Year,"%m/%d/%y")
colnames(final) <- c("Province","Country","Lat","Long","Year","Confirmed")
filter <- filter(final, Country == "Bosnia and Herzegovina" | Country == "Italy" | Country == "Croatia" | Country == "Serbia" | Country == "Slovenia" | Country == "Montenegro" | Country == "Austria" | Country == "North Macedonia" | Country == "Greece")
p <-ggplot(filter, aes(x = Year, y = Confirmed)) +
geom_line(aes(color = Country), size = 1) +
scale_color_brewer(palette="Set1")+
theme(legend.title = element_text(size = 6),legend.text = element_text(size = 6),
# Remove panel background
panel.background = element_blank(),
# Add axis line
axis.line = element_line(colour = "grey"))+
scale_y_log10(labels = comma)+
scale_x_date(date_labels = "%b-%d", date_breaks = "4 week")+
ylab("Confirmed cases")+
labs(caption="Data source: https://github.com/CSSEGISandData/COVID-19")
ggplotly(p)
Total cases per 1 million people
tot_cases_1m <- melt(balkan[,c("Tot.Cases.1M.pop","Country.Other")])
head(tot_cases_1m)
p<-ggplot(tot_cases_1m, aes(x=Country.Other,y=value,fill=Country.Other)) +
geom_bar(stat = "identity")+
scale_fill_manual(name="Country",
values = c("#E41A1C",
"#377EB8",
"#4DAF4A",
"#984EA3",
"#FF7F00",
"#FFFF33",
"#A65628",
"#F781BF",
"#999999"),
labels=c("Austria",
"Bosnia and Herzegovina",
"Croatia",
"Greece",
"Italy",
"Montenegro",
"N.Macedonia",
"Serbia",
"Slovenia"))+
labs(x="",y="Total Cases per 1M people", title = "Total Cases per 1m people - Currently")+
theme(legend.title = element_text(size = 8),
axis.text.x = element_blank(),
legend.text = element_text(size = 8),
panel.background = element_blank(),
axis.line = element_line(colour = "grey"))
ggplotly(p)
NA
Deaths vs Recovered
The bar chart shows the total number of recovered people in comparison to the total number of death cases. Updates daily at around 23:59 UTC.
options(scipen = 9999)
p <- ggplot(balkan) +
geom_segment( aes(x=Country.Other, xend=Country.Other, y=TotalRecovered, yend=TotalDeaths), color="grey") +
geom_point( aes(x=Country.Other, y=TotalRecovered), color=rgb(0.2,0.7,0.1,0.5), size=3 ) +
geom_point( aes(x=Country.Other, y=TotalDeaths), color=rgb(0.7,0.2,0.1,0.5), size=3 ) + coord_flip()+
scale_y_log10()+
theme_minimal() +
theme(
legend.position = "none",
panel.background = element_blank(),
panel.grid = element_blank(),
axis.line = element_line(colour = "grey")) +
xlab("") +
ylab("Number of cases")+
ggtitle(label = "Death vs Recovered")
ggplotly(p)
Active cases vs New cases
The bar chart shows the number of active cases in comparison to the number of new cases being constantly reported.
# Total cases vs new cases
total_and_new <- melt(balkan[,c("TotalCases","NewCases","Country.Other")])
p <- ggplot(total_and_new, aes(x=Country.Other, y=value, fill=variable)) +
geom_bar(stat='identity', position='dodge', color="black" ,aes(text=paste("Country: ",Country.Other, "\n", variable,":",value, sep=""))) +
scale_fill_brewer(palette = "Paired")+
scale_y_continuous(labels=comma, trans = "log10") +
ylab("Number of cases")+
xlab("")+
ggtitle(label = "Total cases vs New cases") +
theme_minimal()+
labs(title = "",fill="" )+
coord_flip()
ggplotly(p, tooltip = "text")
LS0tDQp0aXRsZTogIjA0LUNvdmlkMTlfRGFzaGJvYXJkIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGtlZXBfbWQ6IHRydWUNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KY3NzOiBzdHlsZS5jc3MNCi0tLQ0KDQojIENPVklEIDE5IERhc2hib2FyZCBmb3IgQmFsa2FuIGNvdW50cmllcyoNCg0KOjo6IHsuaW5mb2JveCAuZ3JhcGggZGF0YS1sYXRleD0ie2dyYXBofSJ9DQpbSGVyZSB5b3UgZ28gZGlyZWN0bHkgdG8gdGhlIGRhc2hib2FyZF0oaHR0cHM6Ly9taXJ6YS1tdWphbm92aWMuc2hpbnlhcHBzLmlvL2NvdmlkLTE5LykNCjo6Og0KDQojIyBEYXRhDQoNCmBgYHtyLGVjaG89RkFMU0UsZXJyb3I9RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJ2ZXN0KQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkod2VzYW5kZXJzb24pICAgIA0KbGlicmFyeShzaGlueSkNCmxpYnJhcnkodHdpdHRlUikNCmxpYnJhcnkocnR3ZWV0KQ0KbGlicmFyeShzZW50aW1lbnRyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHB1cnJyKQ0KbGlicmFyeShkZXZ0b29scykNCmxpYnJhcnkodGV4dGRhdGEpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeSh4bWwyKQ0KbGlicmFyeShxZGFwKQ0KbGlicmFyeSh3b3JkY2xvdWQpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoTkxQKQ0KbGlicmFyeSh0bSkNCmxpYnJhcnkodGlkeXRleHQpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkocmVtb3RlcykNCmxpYnJhcnkoamFuZWF1c3RlbnIpDQpsaWJyYXJ5KHFkYXApDQpsaWJyYXJ5KGdsdWUpDQpsaWJyYXJ5KHN5dXpoZXQpDQpgYGANCg0KDQpgYGB7ciwgZXJyb3I9RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIyBHaXRodWIgDQpjb3ZpZDE5X2NvbmZpcm1lZF9naXQgPC0iaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5L21hc3Rlci9jc3NlX2NvdmlkXzE5X2RhdGEvY3NzZV9jb3ZpZF8xOV90aW1lX3Nlcmllcy90aW1lX3Nlcmllc19jb3ZpZDE5X2NvbmZpcm1lZF9nbG9iYWwuY3N2Ig0KY292aWQxOV9jb25maXJtZWRfZ2l0IDwtIHJlYWRfY3N2KHVybChjb3ZpZDE5X2NvbmZpcm1lZF9naXQpKQ0KDQojIFdvcmxkb21ldGVyDQojIyBDb3ZpZA0KY29kaXZpZDE5X2FsbCA8LSAiaHR0cHM6Ly93d3cud29ybGRvbWV0ZXJzLmluZm8vY29yb25hdmlydXMvIg0KbWFpbl90YWJsZSA8LSBjb2RpdmlkMTlfYWxsJT4lDQogIHhtbDI6OnJlYWRfaHRtbCgpJT4lDQogIGh0bWxfbm9kZXMoeHBhdGg9Jy8vKltAaWQ9Im1haW5fdGFibGVfY291bnRyaWVzX3RvZGF5Il0nKSAlPiUNCiAgaHRtbF90YWJsZSgpDQptYWluX3RhYmxlIDwtIGFzLmRhdGEuZnJhbWUobWFpbl90YWJsZSkNCg0KDQpgYGANCg0KDQpgYGB7ciwgZXJyb3I9RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGVjaG89VFJVRX0NCiMjIEZpbHRlcmluZyBkYXRhIGZvciBCYWxrYW4gY291bnRyaWVzIChwbHVzIEl0YWx5IGFuZCBBdXN0cmlhKQ0KYmFsa2FuIDwtIGZpbHRlcihtYWluX3RhYmxlLENvdW50cnkuT3RoZXIgPT0gIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiIHwgQ291bnRyeS5PdGhlciA9PSAiSXRhbHkiIHwgQ291bnRyeS5PdGhlciA9PSAiQ3JvYXRpYSIgfCBDb3VudHJ5Lk90aGVyID09ICJTZXJiaWEiICB8IENvdW50cnkuT3RoZXIgPT0gIk1vbnRlbmVncm8iICB8IENvdW50cnkuT3RoZXIgPT0gIlNsb3ZlbmlhIiAgfCBDb3VudHJ5Lk90aGVyID09ICJBdXN0cmlhIiAgfCBDb3VudHJ5Lk90aGVyID09ICJOb3J0aCBNYWNlZG9uaWEiIHwgQ291bnRyeS5PdGhlciA9PSAiR3JlZWNlIikNCmBgYA0KDQoNCmBgYHtyLCBlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsZWNobz1UUlVFfQ0KIyBSZW1vdmluZyBjb21tYSBmcm9tIG51bWJlcnMNCmJhbGthbltjKCJUb3RhbFJlY292ZXJlZCIsIlRvdGFsRGVhdGhzIiwiVG90YWxDYXNlcyIsIk5ld0Nhc2VzIiwiQWN0aXZlQ2FzZXMiLCJUb3QuQ2FzZXMuMU0ucG9wIildIDwtIGxhcHBseShiYWxrYW5bYygiVG90YWxSZWNvdmVyZWQiLCJUb3RhbERlYXRocyIsIlRvdGFsQ2FzZXMiLCJOZXdDYXNlcyIsIkFjdGl2ZUNhc2VzIiwiVG90LkNhc2VzLjFNLnBvcCIpXSwgZnVuY3Rpb24oeCkgZ3N1YigiLCIsIiIseCkpDQojIFR1cm5pbmcgY29sdW1ucyB0byBudW1lcmljDQpiYWxrYW5bYygiVG90YWxSZWNvdmVyZWQiLCJUb3RhbERlYXRocyIsIlRvdGFsQ2FzZXMiLCJOZXdDYXNlcyIsIkFjdGl2ZUNhc2VzIiwiVG90LkNhc2VzLjFNLnBvcCIpXSA8LSBsYXBwbHkoYmFsa2FuW2MoIlRvdGFsUmVjb3ZlcmVkIiwiVG90YWxEZWF0aHMiLCJUb3RhbENhc2VzIiwiTmV3Q2FzZXMiLCJBY3RpdmVDYXNlcyIsIlRvdC5DYXNlcy4xTS5wb3AiKV0sIGFzLm51bWVyaWMpDQpgYGANCg0KDQojIyBDdXJ2ZSBvZiBjb25maXJtZWQgY2FzZXMgDQoNClRoZSBncmFwaCBzaG93cyB0aGUgbnVtYmVyIG9mIGNvbmZpcm1lZCBjYXNlcyBieSB0aGUgbGFzdCBkYXRlIHNob3duLlVwZGF0ZXMgZGFpbHkgYXQgYXJvdW5kIDIzOjU5IFVUQy4NCg0KYGBge3Isd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD04LGVjaG89VFJVRX0NCiMgQ3VydmUgb2YgY29uZmlybWVkIGNhc2VzLS0tLQ0KY29sdW1ucyA8LSBjb2xuYW1lcyhjb3ZpZDE5X2NvbmZpcm1lZF9naXQpWzU6bmNvbChjb3ZpZDE5X2NvbmZpcm1lZF9naXQpXQ0KZmluYWwgPC1hcy5kYXRhLmZyYW1lKHBpdm90X2xvbmdlcihjb3ZpZDE5X2NvbmZpcm1lZF9naXQsIGNvbHMgPSBjb2x1bW5zLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkNvbmZpcm1lZCIpKQ0KZmluYWwkWWVhciA8LSBhcy5EYXRlLmNoYXJhY3RlcihmaW5hbCRZZWFyLCIlbS8lZC8leSIpDQpjb2xuYW1lcyhmaW5hbCkgPC0gYygiUHJvdmluY2UiLCJDb3VudHJ5IiwiTGF0IiwiTG9uZyIsIlllYXIiLCJDb25maXJtZWQiKSANCmZpbHRlciA8LSBmaWx0ZXIoZmluYWwsIENvdW50cnkgPT0gIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiIHwgQ291bnRyeSA9PSAiSXRhbHkiIHwgQ291bnRyeSA9PSAiQ3JvYXRpYSIgfCBDb3VudHJ5ID09ICJTZXJiaWEiICB8IENvdW50cnkgPT0gIlNsb3ZlbmlhIiAgfCBDb3VudHJ5ID09ICJNb250ZW5lZ3JvIiAgfCBDb3VudHJ5ID09ICJBdXN0cmlhIiB8IENvdW50cnkgPT0gIk5vcnRoIE1hY2Vkb25pYSIgfCBDb3VudHJ5ID09ICJHcmVlY2UiKQ0KcCA8LWdncGxvdChmaWx0ZXIsIGFlcyh4ID0gWWVhciwgeSA9IENvbmZpcm1lZCkpICsgDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBDb3VudHJ5KSwgc2l6ZSA9IDEpICsNCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSxsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksICANCiAgIyBSZW1vdmUgcGFuZWwgYmFja2dyb3VuZA0KICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAjIEFkZCBheGlzIGxpbmUNCiAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5IikpKw0KICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IGNvbW1hKSsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiViLSVkIiwgZGF0ZV9icmVha3MgPSAiNCB3ZWVrIikrDQogIHlsYWIoIkNvbmZpcm1lZCBjYXNlcyIpKw0KICBsYWJzKGNhcHRpb249IkRhdGEgc291cmNlOiBodHRwczovL2dpdGh1Yi5jb20vQ1NTRUdJU2FuZERhdGEvQ09WSUQtMTkiKQ0KZ2dwbG90bHkocCkNCmBgYA0KDQojIyBUb3RhbCBjYXNlcyBwZXIgMSBtaWxsaW9uIHBlb3BsZQ0KDQpgYGB7cixlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQp0b3RfY2FzZXNfMW0gPC0gbWVsdChiYWxrYW5bLGMoIlRvdC5DYXNlcy4xTS5wb3AiLCJDb3VudHJ5Lk90aGVyIildKQ0KaGVhZCh0b3RfY2FzZXNfMW0pDQpwPC1nZ3Bsb3QodG90X2Nhc2VzXzFtLCBhZXMoeD1Db3VudHJ5Lk90aGVyLHk9dmFsdWUsZmlsbD1Db3VudHJ5Lk90aGVyKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikrDQogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWU9IkNvdW50cnkiLA0KICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCIjRTQxQTFDIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIzM3N0VCOCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM0REFGNEEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjOTg0RUEzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI0ZGN0YwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNGRkZGMzMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjQTY1NjI4IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI0Y3ODFCRiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM5OTk5OTkiKSwNCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIkF1c3RyaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQm9zbmlhIGFuZCBIZXJ6ZWdvdmluYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDcm9hdGlhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdyZWVjZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJdGFseSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb250ZW5lZ3JvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk4uTWFjZWRvbmlhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlcmJpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTbG92ZW5pYSIpKSsNCiAgbGFicyh4PSIiLHk9IlRvdGFsIENhc2VzIHBlciAxTSBwZW9wbGUiLCB0aXRsZSA9ICJUb3RhbCBDYXNlcyBwZXIgMW0gcGVvcGxlIC0gQ3VycmVudGx5IikrDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JleSIpKQ0KDQpnZ3Bsb3RseShwKQ0KDQpgYGANCg0KDQoNCg0KIyMgRGVhdGhzIHZzIFJlY292ZXJlZCANCg0KVGhlIGJhciBjaGFydCBzaG93cyB0aGUgdG90YWwgbnVtYmVyIG9mIHJlY292ZXJlZCBwZW9wbGUgaW4gY29tcGFyaXNvbiB0byB0aGUgdG90YWwgbnVtYmVyIG9mIGRlYXRoIGNhc2VzLiBVcGRhdGVzIGRhaWx5IGF0IGFyb3VuZCAyMzo1OSBVVEMuDQoNCmBgYHtyLCBlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsZWNobz1UUlVFfQ0Kb3B0aW9ucyhzY2lwZW4gPSA5OTk5KQ0KcCA8LSBnZ3Bsb3QoYmFsa2FuKSArDQogIGdlb21fc2VnbWVudCggYWVzKHg9Q291bnRyeS5PdGhlciwgeGVuZD1Db3VudHJ5Lk90aGVyLCB5PVRvdGFsUmVjb3ZlcmVkLCB5ZW5kPVRvdGFsRGVhdGhzKSwgY29sb3I9ImdyZXkiKSArDQogIGdlb21fcG9pbnQoIGFlcyh4PUNvdW50cnkuT3RoZXIsIHk9VG90YWxSZWNvdmVyZWQpLCBjb2xvcj1yZ2IoMC4yLDAuNywwLjEsMC41KSwgc2l6ZT0zICkgKw0KICBnZW9tX3BvaW50KCBhZXMoeD1Db3VudHJ5Lk90aGVyLCB5PVRvdGFsRGVhdGhzKSwgY29sb3I9cmdiKDAuNywwLjIsMC4xLDAuNSksIHNpemU9MyApICsgY29vcmRfZmxpcCgpKw0KICBzY2FsZV95X2xvZzEwKCkrDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksDQogIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JleSIpKSArDQogICAgeGxhYigiIikgKw0KICAgIHlsYWIoIk51bWJlciBvZiBjYXNlcyIpKw0KICAgIGdndGl0bGUobGFiZWwgPSAiRGVhdGggdnMgUmVjb3ZlcmVkIikNCmdncGxvdGx5KHApDQpgYGANCg0KIyMgQWN0aXZlIGNhc2VzIHZzIE5ldyBjYXNlcw0KDQpUaGUgYmFyIGNoYXJ0IHNob3dzIHRoZSBudW1iZXIgb2YgIGFjdGl2ZSBjYXNlcyBpbiBjb21wYXJpc29uIHRvIHRoZSBudW1iZXIgb2YgbmV3IGNhc2VzIGJlaW5nIGNvbnN0YW50bHkgcmVwb3J0ZWQuDQoNCmBgYHtyLCBlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsZWNobz1UUlVFfQ0KIyBBY3RpdmUgY2FzZXMgdnMgTmV3IGNhc2VzDQphY3RpdmVfYW5kX25ldyA8LSBtZWx0KGJhbGthblssYygiQWN0aXZlQ2FzZXMiLCJOZXdDYXNlcyIsIkNvdW50cnkuT3RoZXIiKV0pDQpwIDwtIGdncGxvdChhY3RpdmVfYW5kX25ldywgYWVzKHg9Q291bnRyeS5PdGhlciwgeT12YWx1ZSwgZmlsbD12YXJpYWJsZSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbj0nZG9kZ2UnLCBjb2xvcj0iYmxhY2siICxhZXModGV4dD1wYXN0ZSgiQ291bnRyeTogIixDb3VudHJ5Lk90aGVyLCAiXG4iLCB2YXJpYWJsZSwiOiIsdmFsdWUsIHNlcD0iIikpKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9Y29tbWEsIHRyYW5zID0gImxvZzEwIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgY2FzZXMiKSsNCiAgeGxhYigiIikrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgbGFicyh0aXRsZSA9ICIiLGZpbGw9IiIpKw0KICBjb29yZF9mbGlwKCkNCiAgDQpnZ3Bsb3RseShwLCB0b29sdGlwID0gInRleHQiKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCiMjIEhvc3BpdGFsaXphdGlvbg0KDQpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxmaWcuc2hvdz0nYXNpcyd9DQpob3NwaXRhbGl6YXRpb24gPC0gcmVhZC5jc3YoImRhdGEvSG9zcGl0YWxpemF0aW9uX2FsbF9sb2NzLmNzdiIpDQpob3NwaXRhbGl6YXRpb24kWCA8LSBOVUxMDQoNCmNvbHVtbnMgPC0gY29sbmFtZXMoaG9zcGl0YWxpemF0aW9uKVszOm5jb2woaG9zcGl0YWxpemF0aW9uKV0NCnBpdm90X2hvc3BpdGFsaXphdGlvbjwtYXMuZGF0YS5mcmFtZShwaXZvdF9sb25nZXIoaG9zcGl0YWxpemF0aW9uLCBjb2xzID0gY29sdW1ucykpDQpjb2xuYW1lcyhwaXZvdF9ob3NwaXRhbGl6YXRpb24pIDwtIGMoIkNvdW50cnkiLCJEYXRlIiwiVmFyaWFibGUiLCJWYWx1ZSIpIA0KcGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uRVUgPC0gZmlsdGVyKHBpdm90X2hvc3BpdGFsaXphdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlID09ICJhZG1pc19tZWFuInwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlID09ICJhbGxiZWRfbWVhbiJ8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZSA9PSAiYmVkb3Zlcl9tZWFuInwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlID09ICJJQ1ViZWRfbWVhbiJ8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZSA9PSAiaWN1b3Zlcl9tZWFuInwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlID09ICJpbnZWZW5fbWVhbiJ8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZSA9PSAibmV3SUNVX21lYW4iKQ0KcGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uRVUgPC0gZmlsdGVyKHBpdm90X2hvc3BpdGFsaXphdGlvbi5tZWFuLkVVLCBWYWx1ZSA+IDApDQpwaXZvdF9ob3NwaXRhbGl6YXRpb24ubWVhbi5FVSREYXRlIDwtIGFzLkRhdGUoYXMuUE9TSVhjdChwaXZvdF9ob3NwaXRhbGl6YXRpb24ubWVhbi5FVSREYXRlLCIlWSVNJUQiKSkNCmBgYA0KDQojIyMgQ3JvYXRpYQ0KDQpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxmaWcuc2hvdz0nYXNpcyd9DQojQ3JvYXRpYQ0KcGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uY3JvIDwtIGZpbHRlcihwaXZvdF9ob3NwaXRhbGl6YXRpb24ubWVhbi5FVSxDb3VudHJ5ID09ICJDcm9hdGlhIikNCg0KcCA8LSBnZ3Bsb3QocGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uY3JvLGFlcyh4PURhdGUseT1WYWx1ZSkpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1WYXJpYWJsZSksIHNpemU9MSkgKw0KICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKw0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgIA0KICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyZXkiKSkrDQogIHNjYWxlX3lfc3FydCgpKw0KICBnZ3RpdGxlKGxhYmVsID0gIkhvc3BpdGFsaXNhdGlvbiBudW1iZXJzIGluIENyb2F0aWEiKSsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVCLSVkIiwgZGF0ZV9icmVha3MgPSAiNSB3ZWVrIikrDQogIHlsYWIoIk1lYW4iKSsNCiAgbGFicyhjYXB0aW9uPSJEYXRhIHNvdXJjZTogIikNCg0KZ2dwbG90bHkocCkNCmBgYA0KDQojIyMgU2xvdmVuaWEgDQoNCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGZpZy5zaG93PSdhc2lzJ30NCiNTbG92ZW5pYQ0KcGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uc2xvIDwtIGZpbHRlcihwaXZvdF9ob3NwaXRhbGl6YXRpb24ubWVhbi5FVSxDb3VudHJ5ID09ICJTbG92ZW5pYSIpDQoNCnAgPC0gZ2dwbG90KHBpdm90X2hvc3BpdGFsaXphdGlvbi5tZWFuLnNsbyxhZXMoeD1EYXRlLHk9VmFsdWUpKSArDQogIGdlb21fbGluZShhZXMoY29sb3I9VmFyaWFibGUpLCBzaXplPTEpICsNCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSxsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksICANCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5IikpKw0KICBzY2FsZV95X3NxcnQoKSsNCiAgZ2d0aXRsZShsYWJlbCA9ICJIb3NwaXRhbGlzYXRpb24gbnVtYmVycyBpbiBTbG92ZW5pYSIpKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJUItJWQiLCBkYXRlX2JyZWFrcyA9ICI1IHdlZWsiKSsNCiAgeWxhYigiTWVhbiIpKw0KICBsYWJzKGNhcHRpb249IkRhdGEgc291cmNlOiAiKQ0KDQpnZ3Bsb3RseShwKQ0KYGBgDQoNCiMjIyBBdXN0cmlhDQoNCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGZpZy5zaG93PSdhc2lzJ30NCiNBdXN0cmlhDQpwaXZvdF9ob3NwaXRhbGl6YXRpb24ubWVhbi5hdCA8LSBmaWx0ZXIocGl2b3RfaG9zcGl0YWxpemF0aW9uLm1lYW4uRVUsQ291bnRyeSA9PSAiQXVzdHJpYSIpDQoNCnAgPC0gZ2dwbG90KHBpdm90X2hvc3BpdGFsaXphdGlvbi5tZWFuLmF0LGFlcyh4PURhdGUseT1WYWx1ZSkpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1WYXJpYWJsZSksIHNpemU9MSkgKw0KICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKw0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgIA0KICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyZXkiKSkrDQogIHNjYWxlX3lfc3FydCgpKw0KICBnZ3RpdGxlKGxhYmVsID0gIkhvc3BpdGFsaXNhdGlvbiBudW1iZXJzIGluIEF1c3RyaWEiKSsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVCLSVkIiwgZGF0ZV9icmVha3MgPSAiNSB3ZWVrIikrDQogIHlsYWIoIk1lYW4iKSsNCiAgbGFicyhjYXB0aW9uPSJEYXRhIHNvdXJjZTogIikNCg0KZ2dwbG90bHkocCkNCmBgYA0KDQo=